import 'dart:async';
import 'dart:math';
import 'dart:typed_data';

import 'package:lib_bt/BleManager.dart';
import 'package:lib_bt/listener/OnBleDataListener.dart';
import 'package:lib_bt/send/PackageInterface.dart';
import 'package:lib_bt/send/SendBean.dart';
import 'package:lib_bt/send/SendInterface.dart';

import '../../../../AppGlobals.dart';
import '../../../../generated/l10n.dart';
import 'UUIDConfig.dart';

///color系列数据发送实现类
class ColorSendImpl implements OnBleDataListener, SendInterface {
  //计时器
  static Timer? timeout;

  //绑定的蓝牙地址
  late String _address;

  ///待发送数数据
  SendBean? _sendBean;

  //最后发送的数据包
  PackageInterface? _lastPackage;

  ///发送成功回调
  Function(String msg, Uint8List data)? _onSuccess;
  Function(int totalTaskCount, int successTaskCount)? _onProgress;
  Function(String msg, Uint8List data)? _onError;

  ColorSendImpl(String address) {
    _address = address;
    BleManager.instance.addDataListener(this);
  }

  ///发送数据
  void _send(PackageInterface package) {
    _lastPackage = package;
    BleManager.instance.write(_address, package.serviceUuid, package.characteristicUuid, package.data);
  }

  ///判断数据是否以desData开头
  bool startWith(Uint8List srcData, List<int> desData) {
    bool flag = true;

    if (desData.length >= srcData.length) {
      return false;
    }
    if (_lastPackage == null) {
      return false;
    }

    //判断是否是这里发出的数据
    for (int i = 0; i < desData.length; i++) {
      if (_lastPackage!.data[i] == desData[i]) {
        continue;
      } else {
        flag = false;
        break;
      }
    }

    if (flag) {
      //判断回复的数据符合预期
      for (int i = 0; i < desData.length; i++) {
        if (srcData[i] == desData[i]) {
          continue;
        } else {
          flag = false;
          break;
        }
      }
    }

    return flag;
  }

  ///发送下一包数据
  void sendNext(Uint8List srcData) {
    _sendBean?.index++;
    _sendBean?.index = min(_sendBean?.getPackageCount() ?? 0, _sendBean?.index ?? 0);
    //回调发送进度
    _onProgress?.call(_sendBean?.getPackageCount() ?? 0, _sendBean?.index ?? 0);
    var package = _sendBean?.getNextPackage();
    if (package != null) {
      startTimeout();
      _send(package);
      //没有回复的,继续发送下一包
      if (!_sendBean!.hasResponse) {
        sendNext(Uint8List.fromList([]));
      }
    } else {
      stopTimeout();
      //发送完成
      _onSuccess?.call("", srcData);
      _sendBean = null;
      _onSuccess = null;
      _onProgress = null;
      _onError = null;
    }
  }

  ///发送失败统一处理
  void onError(String msg, Uint8List data,{bool isTimeout = false}) {
    _sendBean?.onSendError();
    if(!isTimeout && _sendBean != null && _sendBean!.hasNext()){
      sendNext(data);
    }else{
      //_sendBean?.index = _sendBean?.getPackageCount() ?? 0;
      _onProgress?.call(_sendBean?.getPackageCount() ?? 0, _sendBean?.index ?? 0);
      _onError?.call("", data);
      _sendBean = null;
      _onSuccess = null;
      _onProgress = null;
      _onError = null;
      stopTimeout();
    }
  }

  @override
  void onDataReceived(String address, String uuid, Uint8List data) {
    if (_sendBean == null ||
        _lastPackage == null ||
        address.toLowerCase() != _address.toLowerCase() ||
        uuid.toLowerCase() != UUIDConfig.instance.uuid_notify.toLowerCase()) {
      return;
    }

    if (startWith(data, [0x54, 0x00])) {
      //分包发送过程的回调
      switch (data[8]) {
        case 0x00: //传输失败
        case 0x02: //设备异常
        case 0x03: //数据有误，设置失败，比如数据长度超过最大值
          //发送失败了
          onError("", data);
          break;
        case 0x01: //传输成功,继续发送下一包
          sendNext(data);
          break;
      }
    } else if (startWith(data, [0x54, 0x01])) {
      //分包发送完成的结果
      switch (data[4]) {
        case 1:
          sendNext(data);
          break;
        default:
          onError("", data);
      }
    } else if (startWith(data, [0x54, 0x02])) {
      //清空节目
      switch (data[4]) {
        case 1:
          sendNext(data);
          break;
        default:
          onError("", data);
      }
    } else if (startWith(data, [0x54, 0x03])) {
      //添加节目指令
      switch (data[4]) {
        case 1:
          sendNext(data);
          break;
        default:
          onError("", data);
      }
    } else if (startWith(data, [0x54, 0x06])) {
      //临时节目发送指令
      switch (data[4]) {
        case 1:
          sendNext(data);
          break;
        case 2:
          //空间不足
          onError(S.of(AppGlobals.rootContext).str_common_24, data);
          break;
        case 3:
          //不需要更新,直接回调成功
          _sendBean?.index = _sendBean?.getPackageCount() ?? 0;
          _onProgress?.call(_sendBean?.getPackageCount() ?? 0, _sendBean?.index ?? 0);
          sendNext(data);
          break;
        default:
          onError("", data);
      }
    } else if (startWith(data, [0x54, 0x07])) {
      //选播节目指令
      switch (data[4]) {
        case 1:
          sendNext(data);
          break;
        default:
          onError("", data);
      }
    } else if (startWith(data, [0x54, 0x08])) {
      //完成更新节目播放列表指令
      switch (data[4]) {
        case 1:
          sendNext(data);
          break;
        default:
          onError("", data);
      }
    } else if (startWith(data, [0x54, 0x09])) {
      //设置LED屏亮度指令
      switch (data[4]) {
        case 1:
          sendNext(data);
          break;
        default:
          onError("", data);
      }
    } else if (startWith(data, [0x54, 0x0b])) {
      //设置LED屏旋转角度
      switch (data[4]) {
        case 1:
          sendNext(data);
          break;
        default:
          onError("", data);
      }
    } else if (startWith(data, [0x54, 0x0c])) {
      //校正LED屏时间
      switch (data[4]) {
        case 1:
          sendNext(data);
          break;
        default:
          onError("", data);
      }
    } else if (startWith(data, [0x54, 0x0d])) {
      //查询内置图片总的数量(带内置图片的产品才有效)
      sendNext(data);
    } else if (startWith(data, [0x54, 0x0e])) {
      //设置密码
      switch (data[4]) {
        case 0:
          onError("", data);
          break;
        default:
          sendNext(data);
      }
    } else if (startWith(data, [0x54, 0x0f])) {
      //验证密码
      switch (data[1]) {
        case 0:
          onError("", data);
          break;
        default:
          sendNext(data);
      }
    }
  }

  @override
  void send(SendBean sendBean) {
    _sendBean = sendBean;
    _onSuccess = sendBean.onSuccess;
    _onProgress = sendBean.onProgress;
    _onError = sendBean.onError;
    sendNext(Uint8List.fromList([]));
  }

  ///开始超时倒计时
  void startTimeout() {
    stopTimeout();
    timeout = Timer(const Duration(milliseconds: 3 * 1000), () {
      onError(S.of(AppGlobals.rootContext).str_common_23, Uint8List.fromList([]), isTimeout: true);
    });
  }

  ///停止超时倒计时
  void stopTimeout() {
    if (timeout != null) {
      timeout?.cancel();
      timeout = null;
    }
  }
}
